Skip to content

chore(deps): bundle Dependabot updates + harden dependency review workflows#78

Merged
lelia merged 16 commits into
mainfrom
lelia/dependabot-bundle-hardening
Jul 22, 2026
Merged

chore(deps): bundle Dependabot updates + harden dependency review workflows#78
lelia merged 16 commits into
mainfrom
lelia/dependabot-bundle-hardening

Conversation

@lelia

@lelia lelia commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

What this does

Bundles the open Dependabot updates and hardens the Dependabot config + dependency-review workflow — mirroring socket-sdk-python#84 and socket-python-cli#207 / #217 / #224 — and adds a supply-chain watch for the four core OSS tools Dependabot can't track (OpenGrep / TruffleHog / Trivy / socketdev).

Changes

  • Deps — bundles the 11 open Dependabot PRs below in one verified change (targeted uv lock, no unrelated churn).
  • dependabot.yml — adds the missing uv ecosystem; groups every ecosystem into a minor/patch bundle + a separate major PR.
  • dependency-review.yml (was dependabot-review.yml) — Socket Firewall on every dependency PR: enterprise for all in-repo PRs (maintainers and Dependabot), free for forks, report artifacts, and one always-on required gate. Token is environment-scoped for maintainer runs and mirrored into the Dependabot secret store for Dependabot runs (see "After merge"); no approval rule on the environment.
  • core-tool-watch.yml + scripts/check_core_tools.py — discovers and Socket-scores the four core tools; fails a build on a malware-class or high/critical alert on a pinned version. The scan's Python env is synced from main's lockfile (.scan-env checkout), so the token-holding step never imports packages bumped by the PR under review. OpenGrep has no Socket coverage, so it falls back to a report-only Semgrep-lineage proxy.

Bundled Dependabot PRs

PR Bump
#72 idna 3.10 → 3.18 (CVE-2026-45409)
#71 pygments 2.19.2 → 2.20.0
#70 urllib3 2.6.3 → 2.7.0
#67 pytest 8.4.2 → 9.0.3
#87 requests 2.31.0 → 2.34.2
#76 / #81 docker/metadata-action → 6.1.0
#75 docker/login-action → 4.2.0
#74 docker/build-push-action → 7.2.0
#73 / #86 docker/setup-buildx-action → 4.1.0
#86 actions/setup-python → 6.3.0

After merge

  1. Mark dependency-review-gate as the single required status check on main — but only after this merges (requiring a check that doesn't yet exist on main strands every open PR). Don't add a required-reviewers rule to the socket-firewall environment.
  2. Mirror the SFW token into the Dependabot secret store so Dependabot's own bump PRs get enterprise scoring pre-merge (until then, its runs degrade to free/skipped-scoring with a warning and auto-upgrade once set):
    gh secret set SOCKET_SFW_API_TOKEN --app dependabot
    
Design notes (rationale)
  • Why Dependabot gets enterprise: dependency bumps are exactly where org-policy enforcement matters most. Dependabot-triggered runs read secrets from the Dependabot store only — handed exclusively to runs actually triggered by dependabot[bot], still in the unprivileged read-only pull_request context. This is not the pull_request_target footgun: fork PRs from external contributors can never read these secrets.
  • Why one gate: the enterprise SFW job is skipped on fork PRs, so it can't itself be required (a never-created required check blocks merge forever). dependency-review-gate runs if: always(), needs every conditional job, and fails on any failure/cancelled — so it's always reported and requiring just this one check is safe.
  • Environment, no rule: environment: socket-firewall scopes the token to the enterprise job. A required-reviewers rule on it would be self-approvable yet skippable — friction with no protection — so it's deliberately omitted:
    gh api -X PUT repos/SocketDev/socket-basics/environments/socket-firewall \
      --input - <<<'{"wait_timer":0,"prevent_self_review":false,"reviewers":null,"deployment_branch_policy":null}'
    
  • Degrade-to-free: the enterprise path falls back to free when the token is absent, so secretless contexts never hard-error.
  • Scan-env isolation (core-tool-watch): the sfw smoke jobs necessarily install the PR's bumped packages — screening that install is the job, and sfw is the control. check_core_tools.py has no such control (plain uv sync + SDK import), so its env comes from the default branch's already-scored lockfile while the script only reads the PR's pins. That's what makes handing its job the token on Dependabot PRs safe.
  • Strict fail thresholds: --fail-on-malware intentionally trips on more than literal malware (install scripts, obfuscation, telemetry, typosquat hints, plus any high/critical alert) — for four tools baked into the image, false positives are preferred over silent risk.
  • OpenGrep proxy: Socket has no data for pkg:github/opengrep/opengrep; since OpenGrep is a hard fork of Semgrep, the watcher scores pkg:pypi/semgrep as a project-health proxy — labeled and never build-failing (it doesn't analyze OpenGrep's own artifacts).

Note

Medium Risk
Touches branch-protection-critical CI (new required gate pattern, API token handling on PRs) and bumps several runtime deps including a CVE-related idna fix; misconfiguration of secrets or enabling the gate before merge could block PRs.

Overview
Bundles multiple open Dependabot bumps into pyproject.toml / uv.lock (including requests>=2.33.0 and transitive updates such as idna, urllib3, pytest, pygments, light-s3-client) and refreshes Docker GitHub Actions pins in _docker-pipeline.yml.

Dependabot gains a uv ecosystem entry, minor/patch vs major groups for uv/docker/actions, directories so composite actions under .github/actions/* are scanned, and a 7-day cooldown documented in config comments.

dependabot-review.yml is removed in favor of dependency-review.yml: classifies PRs (Python deps, app_tests Docker, workflow sensitivity, fork vs in-repo trust), runs sfw uv sync via new .github/actions/setup-sfw (enterprise with token degrade-to-free, free for forks), uploads SFW artifacts, smoke-builds app_tests only when its Dockerfile changes, and adds always-on dependency-review-gate as the intended required check.

Adds core-tool-watch.yml and scripts/check_core_tools.py to discover/score OpenGrep, TruffleHog, Trivy, and socketdev pins (watch drift + upsert issues; build mode --fail-on-malware on pinned versions), syncing the scan SDK env from main’s lockfile via a .scan-env checkout.

python-tests.yml switches installs/tests to uv sync --locked and adds uv lock --locked. .gitignore drops the !LICENSE.md exception.

Reviewed by Cursor Bugbot for commit cdbfdce. Configure here.

Bundles 8 open Dependabot PRs into one verified change and hardens the
Dependabot config + dependency-review workflows, mirroring the work in
socket-sdk-python#84 and socket-python-cli#207/#217. Adds a supply-chain
watch for the four core OSS tools Dependabot cannot cleanly track.

- uv.lock: idna 3.10->3.18 (CVE-2026-45409), pygments 2.19.2->2.20.0,
  pytest 8.4.2->9.0.3, urllib3 2.6.3->2.7.0
- _docker-pipeline.yml: bump 4 docker/* actions (setup-buildx, login,
  metadata, build-push)
- dependabot.yml: add uv ecosystem, group every ecosystem into
  minor/patch + major bundles, scan composite actions
- dependency-review.yml (was dependabot-review.yml): runs on every PR;
  free/enterprise sfw split; report artifacts; app_tests docker smoke
- core-tool-watch.yml + scripts/check_core_tools.py: discover latest
  versions of opengrep/trufflehog/trivy/socketdev and score them through
  the Socket API (socketdev SDK purl.post); drift issue + report artifact
- python-tests.yml: uv.lock drift guard

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@lelia
lelia requested a review from a team as a code owner June 2, 2026 23:17
@socket-security

socket-security Bot commented Jun 2, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatedpypi/​pytest@​8.4.2 ⏵ 9.0.387 -3100 +2100100100
Updatedpypi/​requests@​2.31.0 ⏵ 2.34.299 +1100 +4100100100
Updatedpypi/​light-s3-client@​0.0.30 ⏵ 0.0.40100100100 +2100100

View full report

@socket-security-staging

socket-security-staging Bot commented Jun 2, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatedpypi/​pytest@​8.4.2 ⏵ 9.0.387 -3100 +2100100100
Updatedpypi/​requests@​2.31.0 ⏵ 2.34.299 +1100 +4100100100
Updatedpypi/​light-s3-client@​0.0.30 ⏵ 0.0.40100100100100100

View full report

@lelia lelia changed the title chore(deps): bundle dependency updates + harden supply-chain review chore(deps): bundle Dependabot updates + harden dependency review Jun 3, 2026
@lelia lelia changed the title chore(deps): bundle Dependabot updates + harden dependency review chore(deps): bundle Dependabot updates + harden dependency review workflows Jun 3, 2026
@lelia lelia added dependencies Pull requests that update a dependency file github-actions labels Jun 3, 2026
lelia and others added 2 commits June 3, 2026 13:35
… gate

Mirroring the Python CLI/SDK used `environment: socket-firewall` to scope the
SFW token, but that environment can carry a required-reviewers approval gate.
Because the enterprise SFW check can't be a required status check (it would
block Dependabot/fork PRs that only run the free edition), maintainers could
merge without approving the deployment -- the meaningful check silently never
ran, and approvers could rubber-stamp their own PRs. On the scheduled
core-tool-watch job an approval gate would hang the cron run outright.

- Remove `environment:` from python-sfw-smoke-enterprise and core-tool-watch;
  use a plain repo/org SOCKET_SFW_API_TOKEN (zizmor secrets-outside-env is
  already disabled here, so no lint cost). Job split still isolates the token
  to the enterprise job only.
- Add always-on `dependency-review-gate` job: pass when no python deps changed,
  else require the free (Dependabot/fork) or enterprise (maintainer) smoke job
  to have succeeded. Mark THIS as the single required status check -- safe on
  every PR, no manual gate, no bypass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adopt the socket-python-cli#224 pattern uniformly. The environment was never
the problem -- the required-reviewers approval RULE on it was. Keep the
environment for secret scoping; forbid the rule.

- Restore `environment: socket-firewall` on python-sfw-smoke-enterprise and the
  core-tool-watch analyze job so SOCKET_SFW_API_TOKEN is scoped to those jobs.
  Header documents that the environment must have NO reviewers rule, with the
  gh api command to enforce it (reviewers: null).
- dependency-review-gate (Pattern 2 aggregator): now also needs
  docker-smoke-app-tests; fails on any failure/cancelled result (success and
  skipped pass) AND requires the trust-appropriate SFW edition to have
  succeeded when Python deps changed. Runs if: always() so the required context
  is always created -- no Pattern 1 bypass twin needed. Must land on main before
  being added to branch protection.

Signed-off-by: lelia <2418071+lelia@users.noreply.github.com>
…N report

Live CI exposed two things on the now-enabled Actions:
- socketdev/action firewall-enterprise HARD-ERRORS on an empty token (no
  silent fallback), so a trusted dep PR opened before the SOCKET_SFW_API_TOKEN
  secret exists fails and the required gate blocks merge. setup-sfw now resolves
  the effective mode and falls back to firewall-free when enterprise is
  requested without a token -- still a real supply-chain check, ships green
  today, auto-upgrades to enterprise the moment the secret is added. Token is
  read via env, never interpolated into the script.
- socketdev/action writes a structured report to $SFW_JSON_REPORT_PATH; both
  smoke jobs now capture it and upload it alongside the tee'd log.

Signed-off-by: lelia <2418071+lelia@users.noreply.github.com>
@lelia
lelia temporarily deployed to socket-firewall June 26, 2026 20:58 — with GitHub Actions Inactive
@lelia
lelia temporarily deployed to socket-firewall June 26, 2026 20:58 — with GitHub Actions Inactive
@lelia
lelia temporarily deployed to socket-firewall June 26, 2026 21:06 — with GitHub Actions Inactive
@lelia
lelia temporarily deployed to socket-firewall June 26, 2026 21:08 — with GitHub Actions Inactive
… scoring

OpenGrep ships as a GitHub-release binary that Socket has no data for under
its pkg:github coordinate, so the watcher reported 'no data' for it. OpenGrep
is a hard fork of Semgrep, so fall back to scoring the upstream Semgrep
lineage (pkg:pypi/semgrep) as a project-health proxy.

The proxy is report-only and never build-failing: it does not analyze
OpenGrep's own release artifacts, so a Semgrep alert must not block an
OpenGrep build. The pinned/latest verdicts show the proxy result labeled
'(via semgrep upstream proxy)' when the primary coordinate has no data, and
the JSON report records it under a separate 'proxy' key.

The npm 'opengrep' package is a single-version squat (not the official
distribution) and is deliberately not used as a coordinate.

Signed-off-by: lelia <2418071+lelia@users.noreply.github.com>
@lelia
lelia temporarily deployed to socket-firewall June 26, 2026 21:54 — with GitHub Actions Inactive
@lelia
lelia temporarily deployed to socket-firewall June 26, 2026 21:55 — with GitHub Actions Inactive
@lelia
lelia temporarily deployed to socket-firewall July 22, 2026 02:34 — with GitHub Actions Inactive
@lelia
lelia temporarily deployed to socket-firewall July 22, 2026 02:34 — with GitHub Actions Inactive
@lelia

lelia commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

bugbot run

Comment thread scripts/check_core_tools.py
Comment thread .github/workflows/dependency-review.yml
…ore-tool-watch scan env

Dependabot-triggered runs can read a *Dependabot-store* secret (set via
'gh secret set SOCKET_SFW_API_TOKEN --app dependabot'), so the free-tier
routing for Dependabot -- a workaround for the assumption that its runs
could never hold a token -- is gone:

- dependency-review.yml: trusted == any in-repo (non-fork) PR, now
  including Dependabot. Its dep bumps get full org-policy (enterprise)
  enforcement; forks stay on the anonymous free edition. setup-sfw's
  existing empty-token fallback covers the window until the Dependabot
  secret mirror exists.
- core-tool-watch.yml: sync the scan's Python env from the DEFAULT
  BRANCH lockfile (second checkout at .scan-env) so the token-holding
  step never imports packages bumped by the PR under review -- it only
  reads the PR's pins. Makes the Dependabot token mirror safe here too.
- dependency-review.yml: import smokes use 'uv run --no-sync' so the
  post-firewall step can't re-sync outside sfw (Bugbot finding).
- check_core_tools.py: docstring/help now honestly describe the strict
  fail thresholds (curated malware-class list + high/critical), which
  are intentional (Bugbot finding).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lelia
lelia had a problem deploying to socket-firewall July 22, 2026 03:02 — with GitHub Actions Failure
@lelia
lelia temporarily deployed to socket-firewall July 22, 2026 03:02 — with GitHub Actions Inactive
@lelia

lelia commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

bugbot run

The scan env checkout of main fails to build the socket-basics package
editable while main carries the LICENSE.md rename breakage (#79, fix
pending in #88). The scan only imports the dependencies (socketdev SDK),
never socket_basics itself, so skip installing the project entirely --
also insulates this guard from any future main-side packaging breakage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lelia

lelia commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

bugbot run

@lelia
lelia temporarily deployed to socket-firewall July 22, 2026 03:06 — with GitHub Actions Inactive

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 18a01d8. Configure here.

@lelia
lelia temporarily deployed to socket-firewall July 22, 2026 03:07 — with GitHub Actions Inactive

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 425165e. Configure here.

@flowstate Eric Hibbs (flowstate) left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one future-looking nit; LGTM

Comment thread scripts/check_core_tools.py Outdated
… API result

Two related hardenings from external review of purl.post() usage:

- Pass org_slug (resolved via client.org.get) when the installed SDK
  supports it: socketdev >= 3.1 (socket-sdk-python#76) deprecates the
  legacy POST /v0/purl in favor of POST /v0/orgs/{slug}/purl, and a
  future major may drop the legacy route. The pinned 3.0.29 predates
  the parameter, so it is signature-gated -- activates automatically
  when the scan env's lockfile bumps the SDK.

- Raise on an empty purl.post result: the SDK swallows ANY non-200
  (expired token, dropped endpoint, outage) into [], which previously
  flowed through as 'no data' verdicts and exit 0 -- fail-open. Every
  run scores coordinates Socket definitely has data for, so empty is
  an API failure; raising routes it into the existing scoring_error
  fail-closed path under --fail-on-malware.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lelia

lelia commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

bugbot run

@lelia
lelia temporarily deployed to socket-firewall July 22, 2026 23:06 — with GitHub Actions Inactive
@lelia
lelia temporarily deployed to socket-firewall July 22, 2026 23:06 — with GitHub Actions Inactive
Match socket-python-cli's get_org_id_slug() semantics: pass org_slug to
purl.post only when the token maps to exactly one org; multi-org tokens
fall back to the legacy endpoint with a notice rather than guessing and
scoring under the wrong org's policies.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lelia
lelia temporarily deployed to socket-firewall July 22, 2026 23:07 — with GitHub Actions Inactive
@lelia
lelia temporarily deployed to socket-firewall July 22, 2026 23:07 — with GitHub Actions Inactive
Comment thread scripts/check_core_tools.py
Bugbot: a non-empty but incomplete Socket batch (or a pinned coordinate
that never matches a returned analysis row) previously passed as 'no
data' with exit 0 -- the guard could green-light a build without
verifying every pin it exists to gate.

Tools now declare socket_coverage (default True); with a token and a
successful scoring pass, any covered pinned coordinate missing from the
results is collected as unverified and fails a --fail-on-malware run,
listing the exact coordinates. OpenGrep sets socket_coverage=False:
its pkg:github coordinate is the documented no-data case with the
report-only semgrep proxy, and must not perma-fail the guard. The
unverified list is also surfaced in the JSON report.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lelia

lelia commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

bugbot run

@lelia
lelia temporarily deployed to socket-firewall July 22, 2026 23:12 — with GitHub Actions Inactive
@lelia
lelia temporarily deployed to socket-firewall July 22, 2026 23:12 — with GitHub Actions Inactive

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit cdbfdce. Configure here.

@lelia
lelia merged commit cd08db9 into main Jul 22, 2026
17 checks passed
lelia added a commit that referenced this pull request Jul 22, 2026
Resolves conflicts with PR #78 (dependency hardening):
- keep the metadata step removal (tagging moved to merge-manifests)
- adopt bumped docker action pins in the by-digest push and merge job
- revert Dockerfile/.dockerignore to LICENSE (main renamed LICENSE.md back)
- update pipeline header for dependabot-review.yml -> dependency-review.yml

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file github-actions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants